package com.server.service;

import com.server.meta.ClassMeta;
import com.server.meta.FieldMeta;
import com.server.meta.MyAnnotation;
import com.server.util.*;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: sunguangzhu
 * Date: 14-2-13
 * Time: 上午10:26
 * To change this template use File | Settings | File Templates.
 */
public class BeanGeneratorService {
    /**
     * 生成所有bean
     * @throws Exception
     */
    public void generateBeans(GeneratorParams generatorParams) {
        if(generatorParams.getPackageName()==null){
            generatorParams.setPackageName("com."+ Utils.getSplitLast(generatorParams.getPath(),"/"));
        }
        generatorParams.setPackageName(generatorParams.getPackageName()+".model");
        String classPackage = generatorParams.getClassPackage();
        String packageName = generatorParams.getPackageName();
        Set<Class<?>> classes = PackageScan.getClasses(classPackage);
        for (Class<?> clazz : classes) {
            ClassMeta classMeta = new ClassMeta();
            classMeta.setPackageName(packageName);
            classMeta.setClassName(clazz.getSimpleName());
            classMeta.setBaseClassName(clazz.getSuperclass().getSimpleName());
            classMeta.setTableName(HibernateBeanReflectUtils.getTableName(clazz));
            classMeta.setCatalog(HibernateBeanReflectUtils.getTableCatalog(clazz));
            List<FieldMeta> fieldMetas = new ArrayList<FieldMeta>();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                FieldMeta fieldMeta = new FieldMeta();
                fieldMeta.setName(field.getName());
                String fieldTypeName = field.getType().getName();
                if (fieldTypeName.contains(classPackage)) {
                    fieldMeta.setType(field.getGenericType().toString().replace("class", "").replace(classPackage, packageName));
                } else if (fieldTypeName.contains("java.util")) {
                    fieldMeta.setType(field.getGenericType().toString().replace("class", "").replace(classPackage, packageName));
                } else {
                    fieldMeta.setType(fieldTypeName);
                }
                fieldMeta.setUpperName((ReflectUtil.parSetName(field.getName())).replace("set", ""));
                MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
                fieldMeta.setAnnotationFlag(annotation.relation());
                List<String> list = JpaAnnotationUtils.getJapAnnotationList(fieldMeta.getAnnotationFlag(), field, clazz);
                fieldMeta.setJpaAnnotations(list);
                fieldMeta.setComment(annotation.comments());
                fieldMetas.add(fieldMeta);
            }
            classMeta.setFields(fieldMetas);
            Map root = new HashMap();
            root.put("bean", classMeta);

            generatorParams.setTemplateName("bean");
            generatorParams.setRoot(root);
            generatorParams.setFilename(classMeta.getClassName());
            try {
                new GeneratorService().generate(generatorParams);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * single bean
     * @param generatorParams
     */
    public void generateBean(GeneratorParams generatorParams) {
        if(generatorParams.getPackageName()==null){
            generatorParams.setPackageName("com."+ Utils.getSplitLast(generatorParams.getPath(),"/"));
        }
        generatorParams.setPackageName(generatorParams.getPackageName()+".model");
        String packageName = generatorParams.getPackageName();
        String classPackage = generatorParams.getClassPackage();
        Class<?> clazz =generatorParams.getBeanClass();
        ClassMeta classMeta = new ClassMeta();
            classMeta.setPackageName(packageName);
            classMeta.setClassName(clazz.getSimpleName());
            classMeta.setBaseClassName(clazz.getSuperclass().getSimpleName());
            classMeta.setTableName(HibernateBeanReflectUtils.getTableName(clazz));
            classMeta.setCatalog(HibernateBeanReflectUtils.getTableCatalog(clazz));
            List<FieldMeta> fieldMetas = new ArrayList<FieldMeta>();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                FieldMeta fieldMeta = new FieldMeta();
                fieldMeta.setName(field.getName());
                String fieldTypeName = field.getType().getName();
                if (fieldTypeName.contains(classPackage)) {
                    fieldMeta.setType(field.getGenericType().toString().replace("class", "").replace(classPackage, packageName));
                } else if (fieldTypeName.contains("java.util")) {
                    fieldMeta.setType(field.getGenericType().toString().replace("class", "").replace(classPackage, packageName));
                } else {
                    fieldMeta.setType(fieldTypeName);
                }
                fieldMeta.setUpperName((ReflectUtil.parSetName(field.getName())).replace("set", ""));
                MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
                fieldMeta.setAnnotationFlag(annotation.relation());
                List<String> list = JpaAnnotationUtils.getJapAnnotationList(fieldMeta.getAnnotationFlag(), field, clazz);
                fieldMeta.setJpaAnnotations(list);
                fieldMeta.setComment(annotation.comments());
                fieldMetas.add(fieldMeta);
            }
            classMeta.setFields(fieldMetas);
            Map root = new HashMap();
            root.put("bean", classMeta);

            generatorParams.setTemplateName("bean");
            generatorParams.setRoot(root);
            generatorParams.setFilename(classMeta.getClassName());
            try {
                new GeneratorService().generate(generatorParams);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

}
